/**
 *  jQuery.jsonengine.fn.basic
 */
(function($) {
	/**
	 * jQuery.jsonengine テンプレート機能
	 */
	$.jsonengine.utils.template = function(template_, data){
		var tmpl = template_.html(),
		result = "",
		create = function(t,d){
			t = $.jsonengine.utils.createLink(t, d);
			var m = t.match(/{{(.+?)}}/g) || [], r = t;
			$.each( m, function(i,k){
				var v = d[ k.replace(/{|}/g, "") ];
				r = r.replace( k, ( v === undefined ) ? "" : $.jsonengine.utils.escapetag(v) );
			});
			return r;
		};
		if( data === undefined ){ return $( tmpl.replace(/{{(.+?)}}/g, "") ); }
		if( !(data instanceof Array) ){ return $( create(tmpl, data) ); }
		$.each( data, function(i,o){ result += create(tmpl,o); } );
		return $(result);
	};
	/**
	 * jQuery.jsonengine テンプレート機能　リンク生成
	 */
	$.jsonengine.utils.createLink = function(t, d){
		var m = t.match(/<a.*?>(.+?)<\/a>/g) || [], r = t;
		$.each( m, function(i,k){
			var href = k.match(/<a.*?>/g)[0].match(/href=("|').*?("|')/g), v;
			if (href) {
				var src = href[0].match(/("|').*?("|')/g)[0].replace(/("|')/g, "");
				if (src.match(/#/)) {
					v = m[i].replace(href[0], href[0].replace(src, src + '/' + d['_docId']));
				} else {
					v = m[i].replace(href[0], href[0].replace(src, src + '#!' + d['_docId']));
				}
			} else {
				v = $('<p>').append($(k).attr('href', '#!' + d['_docId'])).html();
			}
			r = r.replace( k, ( v === undefined ) ? '' : unescape(v) );
		});
		return r;
	};
	/**
	 * jQuery.jsonengine で用いられるアラート表示です。
	 * ユーザーが再定義する事で表示方法が変えられます。				
	 */
	$.jsonengine.fn.basic.alert = function(message) {
		var aw = $('<div class="jsonengine_alert">')
			.append(message)
			.css({
				margin:0,
				padding:'0.3em',
				background:'yellow',
				position:'fixed',
				top:0,
				display:'none'
			})
			.appendTo('body');
		aw
			.css({left: $('body').outerWidth()/2 - aw.width()/2})
			.fadeIn(200, function() {
				$(this).fadeOut(5000, function(){
					$(this).remove();
				});
				$(this).click(function(){
					$(this).remove();
				});
			});
	};
	/**
	 * jQuery.jsonengine で用いられるログイン警告表示です。
	 * ユーザーが再定義する事で表示方法が変えられます。
	 */
	$.jsonengine.fn.basic.redirectDialog = function(href) {
		if(!href) return;
		$('body').append(
			$('<div>')
				.css({
					margin:0,
					padding:'1em',
					background:'white',
					position:'absolute',
					top:0,
					left:0,
					width:'100%',
					height:'100%'
				})
				.append(
					$('<a>')
						.attr('href',href)
						.append('ログインして下さい')));
	};
	/**
	 * $.jsonengine.fn.basic.success_LOADで使用するリストオブジェクトを返す関数
	 */
	$.jsonengine.fn.basic.list = function(template, response) {
		if(!template) return template;
		template = $(template).clone();
		var partial = $('.partial', template);
		if(!partial.length) partial = template;
		var result = $.jsonengine.utils.template(partial, response);
		partial.children().remove();
		if (result.length) {
			partial.append(result);
		}
		return template;
	};
	/**
	 * jsonengineからデータ読み込み成功した際のコールバック関数
	 */
	$.jsonengine.fn.basic.success_LOAD = function(o, response, status) {
		$.jsonengine.fn.basic.redirectDialog(response.redirect);
		//
		tmp = {};
		tmp.template = o.find('.template');
		if(!tmp.template) return;
		tmp.query = o.find('.query');
		o.empty();
		o.append(tmp.query).append(tmp.template);
		//
		tmp.template.css('display','');
		e = $.jsonengine.fn.basic.list(tmp.template, response);
		tmp.query.css('display','none');
		tmp.template.css('display','none');
		if(e.html().trim()!==''){
			e.attr('class','result');
			o.append(e);
			$('._ie_setform', o).click(function(event){
				object = {
					"type"   :"GET",
					"data"   :{},
					"success":function(o, response, status) {
						$.jsonengine.fn.basic.redirectDialog(response.redirect);
						for (var i=0; i < o.length; i++) {
							o[i].reset();
							$(o[i]).values(response);
						}
					}
				};
				$(this).attr('href').match(/#[^?]+\/(.*)/);
				object.data._docId = RegExp.$1 ? RegExp.$1 : $(this).attr('href').replace('#!','');
				$(this).attr('href').match(/#(.+?)\//);
				object.object = RegExp.$1 ? $('#'+RegExp.$1) : $('form[class^=_je_'+$.jsonengine.fn.docType(o)+']:not(form.search, form.noset)');
				$.jsonengine.fn.base(object);
				return false;
			});
			$('._ie_setview', o).click(function(){
				object = {
					"type"   :"GET",
					"data"   :{},
					"success":$.jsonengine.fn.basic.success_LOAD
				};
				$(this).attr('href').match(/#[^?]+\/(.*)/);
				object.data._docId = RegExp.$1 ? RegExp.$1 : $(this).attr('href').replace('#!','');
				$(this).attr('href').match(/#(.+?)\//);
				var tmp = RegExp.$1 ? $('#'+RegExp.$1) : $('*:[class^=_je_'+$.jsonengine.fn.docType(o)+']:not(form:[class^=_je_], input:[class^=_je_], select:[class^=_je_]), textarea:[class^=_je_], button:[class^=_je_]');
				object.object = [];
				for(var i=0; i<tmp.length; i++){
					if($('.query',tmp[i]).text() === '_docId'){
						object.object = $(tmp[i]);
						$.jsonengine.fn.base(object);
					}
				}
				return false;
			});
			$('._crud_DELETE', o).click(function(){
				if(!window.confirm('Are you sure?')) return false;
				var docType = $.jsonengine.fn.docType(o);
				var docId = $(this).attr('href').replace('#!','');
				var success_del = function(obj, response, status) {
					$.jsonengine.fn.basic.redirectDialog(response.redirect);
					$('*:[class^=_je_'+docType+']:not(form:[class^=_je_], input:[class^=_je_], select:[class^=_je_], textarea:[class^=_je_], button:[class^=_je_])')._LOAD();
//					$('form[class^=_je_'+docType+']:not(form.search, form.noset)').get(0).reset();
					$.jsonengine.fn.basic.alert('削除しました');
				};
				$.jsonengine.ajax({
					"type"    : "DELETE",
					"url"     : "/_je/" + docType + "/" + docId,
					"success" : $.jsonengine.success(o, success_del),
					"error"   : $.jsonengine.error(o, $.jsonengine.fn.basic.error_DELETE)
				});
				return false;
			});
		}
	};
	/**
	 * jsonengineからデータ読み込み失敗した際のコールバック関数
	 */
	$.jsonengine.fn.basic.error_LOAD = function(o, xhr, status, thrown){
//		o.append($('<div class="error">')
//			.append('status:')
//				.append($('<span style="color:red;font-weight:bold;">')
//					.append(status)));
		$.jsonengine.fn.basic.alert('データを取得できませんでした');
	};
	/**
	 * jsonengineから1件取得が成功した際のコールバック関数
	 */
	$.jsonengine.fn.basic.success_GET = function(o, response, status) {
		$.jsonengine.fn.basic.redirectDialog(response.redirect);
		o.reset();
		$(o).values(response);
	};
	/**
	 * jsonengineから1件取得がが失敗した際のコールバック関数
	 */
	$.jsonengine.fn.basic.error_GET= function(o, xhr, status, thrown){
		$.jsonengine.fn.basic.alert('データを取得できませんでした');
	};
	/**
	 * jsonengineへ新規登録が成功した際のコールバック関数
	 */
	$.jsonengine.fn.basic.success_POST = function(o, response, status) {
		$.jsonengine.fn.basic.redirectDialog(response.redirect);
		if ($(o).attr('class').match(/afterclear/)) {
			o.reset();
		} else {
			$(o).values(response);
		}
		$('*:[class^=_je_'+$.jsonengine.fn.docType(o)+']:not(form:[class^=_je_], input:[class^=_je_], select:[class^=_je_], textarea:[class^=_je_], button:[class^=_je_])')._LOAD();
		$.jsonengine.fn.basic.alert('更新しました');
	};
	/**
	 * jsonengineへ新規登録が失敗した際のコールバック関数
	 */
	$.jsonengine.fn.basic.error_POST = function(o, xhr, status, thrown){
		$.jsonengine.fn.basic.alert('更新できませんでした');
	};
	/**
	 * jsonengineへ更新が成功した際のコールバック関数
	 */
	$.jsonengine.fn.basic.success_PUT = function(o, response, status) {
		$.jsonengine.fn.basic.redirectDialog(response.redirect);
		if ($(o).attr('class').match(/afterclear/)) {
			o.reset();
		} else {
			$(o).values(response);
		}
		$('*:[class^=_je_'+$.jsonengine.fn.docType(o)+']:not(form:[class^=_je_], input:[class^=_je_], select:[class^=_je_], textarea:[class^=_je_], button:[class^=_je_])')._LOAD();
		$.jsonengine.fn.basic.alert('更新しました');
	};
	/**
	 * jsonengineへ更新が失敗した際のコールバック関数
	 */
	$.jsonengine.fn.basic.error_PUT = function(o, xhr, status, thrown){
		$.jsonengine.fn.basic.alert('更新できませんでした');
	};
	/**
	 * jsonengineで削除が成功した際のコールバック関数
	 */
	$.jsonengine.fn.basic.success_DELETE = function(o, response, status) {
		$.jsonengine.fn.basic.redirectDialog(response.redirect);
		o.reset();
		$('*:[class^=_je_'+$.jsonengine.fn.docType(o)+']:not(form:[class^=_je_], input:[class^=_je_], select:[class^=_je_], textarea:[class^=_je_], button:[class^=_je_])')._LOAD();
		$.jsonengine.fn.basic.alert('削除しました');
	};
	/**
	 * jsonengineで削除が失敗した際のコールバック関数
	 */
	$.jsonengine.fn.basic.error_DELETE = function(o, xhr, status, thrown){
		$.jsonengine.fn.basic.alert('削除できませんでした');
	};;
})(jQuery);

